#ifndef CHATTINGROOM_H
#define CHATTINGROOM_H

#include"ChatRoom.h"
#include<time.h>
#include<thread>
#include<mutex>

using namespace std;
namespace fs=filesystem;




/*
    聊天室消息通知管理器,维护用户的消息通知列表。
*/
class MsgReciver{
    struct MsgNotify{
        int sender_id; //消息接收者id
        string chat_room_id;//聊天室id
        int num_msg;//消息数量

        void send_out_msg_notify(); //发送消息通知
    };
    
    //存储消息通知的文件夹路径
    static constexpr const char* MSG_NOTIFY_FILE_DIR = "data/msg_notify/";

    using MsgNotify_ptr=shared_ptr<MsgNotify>;
    unordered_map<int,MsgNotify_ptr> msg_notifies; //消息通知列表
    int delay_time; //消息通知延迟时间

    public:
        //向列表中添加消息通知
        void add_msg_notify(const int& user_id,const int& sender_id,const string& chat_room_id,const int& num_msg); //添加消息通知

        string get_msg_notify_file_path(const int& user_id) const; //获得消息通知文件路径

        void load_msg_notify(const int& user_id); //加载消息通知

        void save_msg_notify(const int& user_id); //保存消息通知
        
        void listen_msg_notify(); //监听消息通知队列，发送消息通知
};


/*
    负责聊天室管理,维护聊天室记录。

    内置一个队列，将消息添加到队列中；
    定期清除缓存并保存聊天记录到文件。

    客户端请求聊天室内容时，先查看缓存，如果缓存中没有，则从文件中加载。
    (用户的聊天室列表由UserManager维护)
*/
class ChattingRoomManager {
    using chat_history_t=shared_ptr<deque<unique_ptr<Msg>>>; //聊天记录



    using ChatRoom_ptr=shared_ptr<ChatRoom>;

    static constexpr const char* CHAT_FILE_DIR = "data/chat/";
    static constexpr const int MAX_CHAT_CONTENT_SIZE = 1000; //聊天记录最大容量

    private:
        //聊天室列表缓存,key为聊天室id,value为聊天记录
        unordered_map<string,ChatRoom_ptr> chat_rooms; 

        //获取聊天室文件路径
        string GetChatRoomFilePath(const string& chat_id) const;

        //打开文件
        void open_file(const string& file_path,ofstream& ofs) const;
        void open_file(const string& file_path,ifstream& ifs) const;

        //存储文件,保存聊天记录,定期清理缓存并保存聊天记录到文件
        void save_file(const string&path,const ChatRoom_ptr& chat_room) const;

        //加载聊天室内容,
        ChatRoom_ptr LoadChatRoomContent(const string& chat_id);

        //保存聊天室内容，遍历缓存并保存到文件
        
        bool is_clear_chatroom_cache_on=true;
        mutable mutex chat_room_mutex; //聊天室锁
        
        public:
        
        void SaveChatRoomContent();
        //加载聊天室记录，先检查缓存，如果缓存中没有，则从文件中加载,如果文件错误或不存在返回-1,成功返回0
        int QuickLoadChatContent(const string&chat_id,ChatRoom_ptr& chat_room);//1

        //加载聊天室记录，先检查缓存，如果缓存中没有，则从文件中加载,如果文件错误或不存在返回-1,成功返回0
        int QuickLoadChatContent(const string&chat_id,json& chat_content);//1

        //请求最新的聊天记录
        int GetLatestChatMsg(const string& chat_id,const int& num_msg,deque<shared_ptr<Msg>>& chat_msg);//1
        int GetLatestChatMsg(const string& chat_id,const int& num_msg,json& chat_msg);//1

        //向对应聊天室添加聊天记录,最多保存MAX_CHAT_CONTENT_SIZE条记录
        int AddChatMsg(const string& chat_id,shared_ptr<Msg> msg);//1

        //创建聊天室
        //返回是否创建成功,成功返回0,失败返回-1
        int CreateChatRoom(const int&owner_id,const string&chat_id,const string&chat_name);//1
        //返回一个新的聊天室id,失败返回空字符串
        string CreateChatRoom(const int&owner_id,const string&chat_name);//1


        //删除聊天室
        bool DeleteChatRoom(const string& chat_id,const int&request_user_id,string &info)=delete;

        int DeleteChatRoom(const string& chat_id,const int&request_user_id);//1

        //加入聊天室
        void JoinChatRoom(const string& chat_id,const int& user_id,const string &user_name,string&info)=delete;
        int JoinChatRoom(const string& chat_id,const int& user_id,const string &user_name);//1

        //退出聊天室
        int ExitChatRoom(const string& chat_id,const int& user_id);//1

        //判断聊天室是否存在
        bool is_chat_room_exist(const string& chat_id) const;//1

        //判断用户是否是聊天室所有者
        bool is_owner(const string& chat_id,const int& user_id) ;//1

        //用于多线程的定时清理缓存,并存储到文件
        void clear_chat_room_cache_func(int clear_freqency);//1

};
#endif